package org.artifact.core.lang;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.CharsetUtil;
import org.artifact.core.cache.AbstractCache;
import org.artifact.core.util.CommonUtil;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.Pipeline;

import java.util.ArrayList;
import java.util.Arrays;

public class RedisScript {
    private static byte[] REMOVE_SCRIPT;
    private static byte[] PUT_SCRIPT;
    private static byte[] REMOVE_SCRIPT2;
    private static byte[] PUT_SCRIPT2;
    private static byte[] INDEX_SCRIPT;
    private static byte[] UNIQUE_SCRIPT;

    public static void init(Jedis jedis) {
        try {

//            REMOVE_SCRIPT = jedis.scriptLoad(ResourceUtil.readUtf8Str("file:redis_lua/removeById.lua")).getBytes();
//            PUT_SCRIPT = jedis.scriptLoad(ResourceUtil.readUtf8Str("file:redis_lua/put.lua")).getBytes();
//            INDEX_SCRIPT = jedis.scriptLoad(ResourceUtil.readUtf8Str("file:redis_lua/getByIndex.lua")).getBytes();
//            UNIQUE_SCRIPT = jedis.scriptLoad(ResourceUtil.readUtf8Str("file:redis_lua/getByUnique.lua")).getBytes();

            REMOVE_SCRIPT = jedis.scriptLoad(FileUtil.readString(ResourceUtil.getResourceObj("redis_lua/removeById.lua").getUrl(), CharsetUtil.UTF_8)).getBytes();
            PUT_SCRIPT = jedis.scriptLoad(FileUtil.readString(ResourceUtil.getResourceObj("redis_lua/put.lua").getUrl(), CharsetUtil.UTF_8)).getBytes();
            REMOVE_SCRIPT2 = jedis.scriptLoad(FileUtil.readString(ResourceUtil.getResourceObj("redis_lua/removeById2.lua").getUrl(), CharsetUtil.UTF_8)).getBytes();
            PUT_SCRIPT2 = jedis.scriptLoad(FileUtil.readString(ResourceUtil.getResourceObj("redis_lua/put2.lua").getUrl(), CharsetUtil.UTF_8)).getBytes();
            INDEX_SCRIPT = jedis.scriptLoad(FileUtil.readString(ResourceUtil.getResourceObj("redis_lua/getByIndex.lua").getUrl(), CharsetUtil.UTF_8)).getBytes();
            UNIQUE_SCRIPT = jedis.scriptLoad(FileUtil.readString(ResourceUtil.getResourceObj("redis_lua/getByUnique.lua").getUrl(), CharsetUtil.UTF_8)).getBytes();
        } finally {
            jedis.close();
        }
    }

    public static void main(String[] args) {
        JedisPool jedisPool = new JedisPool("127.0.0.1", 6379);
        Jedis jedis = jedisPool.getResource();

//        // 唯一索引
//        Console.log(getByUnique(jedis, "t_role", "t_role:unique:", "uid_sid:1273792413281943552|1001"));
//
//        // 唯一索引
//        Console.log(getByIndex(jedis, "t_role", "t_role:index:number:27522200"));
//
//        // 添加
//        put(jedis, "t_test", "t_index_hash", "1", "dsta".getBytes(), new String[]{"sandKing:unique:123456", "sojoys:index:456789" });

        //删除
        remove(jedis, "t_test", "t_index_hash", "1");
    }


    // 根据聚集索引获取
    public static void remove(Pipeline pipeline, String table, String indexHashes, Object primaryKey) {
        byte[] _table = CommonUtil.toBytes(table);
        byte[] _primaryKey = CommonUtil.toBytes(primaryKey);
        byte[] _indexHashes = CommonUtil.toBytes(indexHashes);
        pipeline.evalsha(REMOVE_SCRIPT, Arrays.asList(_table, _primaryKey, _indexHashes), new ArrayList<>());
    }

    // 根据聚集索引获取
    public static void put(Pipeline pipeline, String table, String indexHashes, Object primaryKey, byte[] data, String[] indexs) {
        byte[] _table = CommonUtil.toBytes(table);
        byte[] _primaryKey = CommonUtil.toBytes(primaryKey);
        byte[] _indexHashes = CommonUtil.toBytes(indexHashes);
        ArrayList<byte[]> _indexs = new ArrayList<>(indexs.length);
        // 添加All索引
        _indexs.add(CommonUtil.toBytes(CommonUtil.getIndex(AbstractCache.PREFIX_ALL, ":index:")));
        for (int i = 0; i < indexs.length; i++) {
            _indexs.add(CommonUtil.toBytes(indexs[i]));
        }
        pipeline.evalsha(PUT_SCRIPT, Arrays.asList(_table, _primaryKey, _indexHashes, data), _indexs);
    }

    // 根据聚集索引获取
    public static ArrayList<byte[]> remove(Jedis jedis, String table, String indexHashes, Object primaryKey) {
        byte[] _table = CommonUtil.toBytes(table);
        byte[] _primaryKey = CommonUtil.toBytes(primaryKey);
        byte[] _indexHashes = CommonUtil.toBytes(indexHashes);
        Object result = jedis.evalsha(REMOVE_SCRIPT, Arrays.asList(_table, _primaryKey, _indexHashes), new ArrayList<>());
        return (ArrayList<byte[]>) result;
    }

    // 根据聚集索引获取
    public static ArrayList<byte[]> put(Jedis jedis, String table, String indexHashes, Object primaryKey, byte[] data, String[] indexs) {
        byte[] _table = CommonUtil.toBytes(table);
        byte[] _primaryKey = CommonUtil.toBytes(primaryKey);
        byte[] _indexHashes = CommonUtil.toBytes(indexHashes);
        ArrayList<byte[]> _indexs = new ArrayList<>(indexs.length);
        // 添加All索引
        _indexs.add(CommonUtil.toBytes(CommonUtil.getIndex(AbstractCache.PREFIX_ALL, ":index:")));
        for (int i = 0; i < indexs.length; i++) {
            _indexs.add(CommonUtil.toBytes(indexs[i]));
        }
        Object result = jedis.evalsha(PUT_SCRIPT, Arrays.asList(_table, _primaryKey, _indexHashes, data), _indexs);
        return (ArrayList<byte[]>) result;
    }


    // 根据聚集索引获取
    public static void remove2(Pipeline pipeline, String table, String indexHashes, Object primaryKey) {
        byte[] _table = CommonUtil.toBytes(table);
        byte[] _primaryKey = CommonUtil.toBytes(primaryKey);
        byte[] _indexHashes = CommonUtil.toBytes(indexHashes);
        pipeline.evalsha(REMOVE_SCRIPT2, Arrays.asList(_table, _primaryKey, _indexHashes), new ArrayList<>());
    }

    // 根据聚集索引获取
    public static void put2(Pipeline pipeline, String table, String indexHashes, Object primaryKey, byte[] data, String[] indexs) {
        byte[] _table = CommonUtil.toBytes(table);
        byte[] _primaryKey = CommonUtil.toBytes(primaryKey);
        byte[] _indexHashes = CommonUtil.toBytes(indexHashes);
        ArrayList<byte[]> _indexs = new ArrayList<>(indexs.length);
        // 添加All索引
        _indexs.add(CommonUtil.toBytes(CommonUtil.getIndex(AbstractCache.PREFIX_ALL, ":index:")));

        for (int i = 0; i < indexs.length; i++) {
            _indexs.add(CommonUtil.toBytes(indexs[i]));
        }
        pipeline.evalsha(PUT_SCRIPT2, Arrays.asList(_table, _primaryKey, _indexHashes, data), _indexs);
    }

    // 根据聚集索引获取
    public static ArrayList<byte[]> remove2(Jedis jedis, String table, String indexHashes, Object primaryKey) {
        byte[] _table = CommonUtil.toBytes(table);
        byte[] _primaryKey = CommonUtil.toBytes(primaryKey);
        byte[] _indexHashes = CommonUtil.toBytes(indexHashes);
        Object result = jedis.evalsha(REMOVE_SCRIPT2, Arrays.asList(_table, _primaryKey, _indexHashes), new ArrayList<>());
        return (ArrayList<byte[]>) result;
    }

    // 根据聚集索引获取
    public static ArrayList<byte[]> put2(Jedis jedis, String table, String indexHashes, Object primaryKey, byte[] data, String[] indexs) {
        byte[] _table = CommonUtil.toBytes(table);
        byte[] _primaryKey = CommonUtil.toBytes(primaryKey);
        byte[] _indexHashes = CommonUtil.toBytes(indexHashes);
        ArrayList<byte[]> _indexs = new ArrayList<>(indexs.length);

        // 添加All索引
        _indexs.add(CommonUtil.toBytes(CommonUtil.getIndex(AbstractCache.PREFIX_ALL, ":index:")));

        for (int i = 0; i < indexs.length; i++) {
            _indexs.add(CommonUtil.toBytes(indexs[i]));
        }
        Object result = jedis.evalsha(PUT_SCRIPT2, Arrays.asList(_table, _primaryKey, _indexHashes, data), _indexs);
        return (ArrayList<byte[]>) result;
    }


    // 根据聚集索引获取
    public static ArrayList<byte[]> getByIndex(Jedis jedis, String table, String table_index) {
        byte[] _table = CommonUtil.toBytes(table);
        byte[] _table_index = CommonUtil.toBytes(table_index);
        Object result = jedis.evalsha(INDEX_SCRIPT, Arrays.asList(_table, _table_index), new ArrayList<>());
        return (ArrayList<byte[]>) result;
    }

    // 根据唯一索引获取
    public static byte[] getByUnique(Jedis jedis, String table, String table_unique, String unique) {
        byte[] _table = CommonUtil.toBytes(table);
        byte[] _table_unique = CommonUtil.toBytes(table_unique);
        byte[] _unique = CommonUtil.toBytes(unique);
        Object result = jedis.evalsha(UNIQUE_SCRIPT, Arrays.asList(_table, _table_unique, _unique), new ArrayList<>());
        return (byte[]) result;
    }
//
//
//    public static byte[] toBytes(Object obj) {
//        byte[] bytes = null;
//        if (obj instanceof String) {
//            String v = (String) obj;
//            try {
//                bytes = v.getBytes(CharsetUtil.UTF_8);
//            } catch (UnsupportedEncodingException e) {
//                e.printStackTrace();
//            }
//        } else if (obj instanceof Integer) {
//            int v = (int) obj;
//            bytes = new byte[4];
//            BitUtil.putInt(bytes, 0, v);
//        } else if (obj instanceof Long) {
//            long v = (long) obj;
//            bytes = new byte[8];
//            BitUtil.putLong(bytes, 0, v);
//        }
//        return bytes;
//    }
}
